/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package PanelesDePlatos;

import PanelesDeTrabajo.PanelPrincipalPlato;
import com.google.gson.Gson;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.table.DefaultTableModel;
import net.miginfocom.swing.MigLayout;

/**
 *
 * @author Karlitox
 */
public class ModificarPlato extends JPanel implements ActionListener, MouseListener
{
    private JPanel panelDatos;
    private JPanel panelTabla;
    private JPanel panelDescripcion;
    private JPanel panelFoto;
    private JLabel labelNombreBox, labelNombre, labelFotoVacia, labelPrecio, labelValoracion, labelIngrediente, labelReemplazar,labelPeso, labelAporteCalorico, labelDescripcion, labelRecomendacion, labelFoto;
    private JTextField textoNombre, textoPrecio, textoValoracion, textoIngrediente, textoReemplazar,textoPeso, textoAporteCalorico;
    private JTextArea areaDescripcion, areaRecomendacion;
    private JButton buscarFoto, agregarIngrediente, modificarPlato, eliminarIngrediente, reemplazarIngrediente;
    private JTable tabla;
    private DefaultTableModel modelo;
    private JScrollPane scroll, scrollDescripcion, scrollRecomendacion;
    private ImageIcon icon;
    private String rutaAbsolutaImg;
    private int filaTabla;
    private int indicePlatoModificado;
    private int indiceTablaModificable;
    private JComboBox comboBoxPlatos;
    private JComboBox comboBoxIngredientes;
    private ArrayList<Plato> platos = new ArrayList<Plato>();
    private Gson gson = new Gson(); 
    private boolean estaEscrito = false;
    private boolean modificadoIngrediente = false;

    public ModificarPlato() {
        this.setLayout(new BorderLayout());
        
        icon = new ImageIcon("src/Resource/sin_foto.PNG");
        ImageIcon icon2 = new ImageIcon(icon.getImage().getScaledInstance(100, 130, Image.SCALE_DEFAULT));
        
        this.panelDatos = new JPanel();
        this.panelDatos.setLayout(new MigLayout());
        
        this.panelTabla = new JPanel();
        this.panelTabla.setLayout(new MigLayout());
        
        this.panelDescripcion = new JPanel();
        this.panelDescripcion.setLayout(new MigLayout());
        
        this.panelFoto = new JPanel();
        this.panelFoto.setSize(new Dimension(10, 10));
        this.panelFoto.setLayout(new MigLayout());
        JLabel label = new JLabel(icon2);
        this.panelFoto.add(label);
        
        this.comboBoxPlatos = new JComboBox();
        this.comboBoxIngredientes = new JComboBox();
        
        this.labelNombreBox = new JLabel("Nombre");
        this.labelNombre = new JLabel("Nombre");
        this.labelFotoVacia = new JLabel("Foto");
        this.labelPrecio = new JLabel("Precio $");
        this.labelValoracion = new JLabel("Valoración");
        this.labelIngrediente = new JLabel("Ingrediente");
        this.labelReemplazar = new JLabel("Ingrediente");
        this.labelPeso = new JLabel("Peso Kg");
        this.labelAporteCalorico = new JLabel("Aporte Calórico");
        this.labelDescripcion = new JLabel("Descripción");
        this.labelRecomendacion = new JLabel("Recomendación");
        this.labelFoto = new JLabel();
        
        this.textoNombre = new JTextField(20);
        this.textoPrecio = new JTextField(20);
        this.textoValoracion = new JTextField(20);
        this.textoIngrediente = new JTextField(20);
        this.textoReemplazar = new JTextField(10);
        this.textoPeso = new JTextField(20);
        this.textoAporteCalorico = new JTextField(20);
        
        this.areaDescripcion = new JTextArea(5, 25);
        this.areaRecomendacion = new JTextArea(5, 25);
        
        this.buscarFoto = new JButton("Examinar");
        this.agregarIngrediente = new JButton("Agregar");
        this.modificarPlato = new JButton("Modificar Plato");
        this.eliminarIngrediente = new JButton("Eliminar Ingrediente");
        this.reemplazarIngrediente = new JButton("Reemplazar");
        
        this.modificarPlato.addActionListener(this);
        this.agregarIngrediente.addActionListener(this);
        this.eliminarIngrediente.addActionListener(this);
        this.buscarFoto.addActionListener(this);
        this.reemplazarIngrediente.addActionListener(this);
        
        this.modelo = new DefaultTableModel();
        this.tabla = new JTable(modelo);
        this.tabla.getTableHeader().setReorderingAllowed(false);
        this.tabla.addMouseListener(this);
        this.modelo.addColumn("Nombre Ingredientes");
        this.scroll = new JScrollPane(tabla);
        this.scroll.setViewportView(tabla);
        this.scrollDescripcion = new JScrollPane(areaDescripcion);
        this.scrollRecomendacion = new JScrollPane(areaRecomendacion);
        
        this.panelDatos.add(labelNombreBox);
        llenarComboBoxPlatos();
        this.panelDatos.add(comboBoxPlatos);
        this.panelDatos.add(labelValoracion);
        this.panelDatos.add(textoValoracion, "wrap");
        this.panelDatos.add(labelFotoVacia);
        this.panelDatos.add(buscarFoto);
        this.panelDatos.add(labelIngrediente);
        this.panelDatos.add(textoIngrediente);
        this.panelDatos.add(agregarIngrediente, "wrap");
        this.panelDatos.add(labelPrecio);
        this.panelDatos.add(textoPrecio);
        this.panelDatos.add(labelPeso);
        this.panelDatos.add(textoPeso, "wrap");
        this.panelDatos.add(labelAporteCalorico);
        this.panelDatos.add(textoAporteCalorico);
        this.panelDatos.add(labelNombre);
        this.panelDatos.add(textoNombre);
        this.panelDatos.add(labelReemplazar);
        this.panelDatos.add(comboBoxIngredientes);
        this.panelDatos.add(textoReemplazar);
        this.panelDatos.add(reemplazarIngrediente, "wrap");
        
        this.panelTabla.add(scroll, "wrap");
        this.panelTabla.add(eliminarIngrediente);
        
        this.panelDescripcion.add(panelFoto, "wrap");
        this.panelDescripcion.add(labelDescripcion, "wrap");
        this.panelDescripcion.add(scrollDescripcion, "wrap");
        this.panelDescripcion.add(labelRecomendacion, "wrap");
        this.panelDescripcion.add(scrollRecomendacion, "wrap");
        this.panelDescripcion.add(modificarPlato);
        
        this.comboBoxPlatos.addActionListener(this);
        
        this.add(panelDatos, BorderLayout.NORTH);
        this.add(panelTabla, BorderLayout.WEST);
        this.add(panelDescripcion, BorderLayout.EAST);
    }
    
    @Override
    public void actionPerformed(ActionEvent e) 
    {
        Object click = e.getSource();
        
        boolean nombreVacio = textoNombre.getText().isEmpty();
        boolean valoracionVacio = textoValoracion.getText().isEmpty();
        boolean precioVacio = textoPrecio.getText().isEmpty();
        boolean ingredienteVacio = textoIngrediente.getText().isEmpty();
        boolean aporteCaloricoVacio = textoAporteCalorico.getText().isEmpty();
        boolean descripcionVacio = areaDescripcion.getText().isEmpty();
        boolean recomendacionVacio = areaRecomendacion.getText().isEmpty();
        
        if (click == modificarPlato)
        {
            if (nombreVacio || valoracionVacio || precioVacio || aporteCaloricoVacio ||  //FALTAAA NOMBREEEEEEE!!!
                descripcionVacio || recomendacionVacio || modelo.getRowCount() == 0) //Está vacío?
            {
                JOptionPane.showMessageDialog(this, "Faltan campos por completar y/o ingredientes por agregar, por favor complete todos los campos pedidos y/o agregue ingredientes.");
            }
            else
            {
                String nombre = textoNombre.getText();
                String descripcion = areaDescripcion.getText();
                String recomendacion = areaRecomendacion.getText();
                double valoracion = Double.parseDouble(textoValoracion.getText());
                float peso = Float.parseFloat(textoPeso.getText());
                int precio = Integer.parseInt(textoPrecio.getText());
                int aporteCalorico = Integer.parseInt(textoAporteCalorico.getText());
                
                Plato plato = new Plato(nombre, valoracion, precio, peso, aporteCalorico, descripcion, recomendacion, rutaAbsolutaImg, null);
                modificarIngredientes(plato);
                reemplazarPlatoModificado(plato);
                
                try 
                {
                    vaciarTxt();
                    reescribirTxt();
                } 
                catch (IOException ex) 
                {
                    Logger.getLogger(ModificarPlato.class.getName()).log(Level.SEVERE, null, ex);
                }
                
                JOptionPane.showMessageDialog(this, "Su plato fue modificado con éxito.");
            }
        }
        if (click == agregarIngrediente)
        {
            if (ingredienteVacio)
            {
                JOptionPane.showMessageDialog(this, "No se ha especificado algún ingrediente, por favor agregue un ingrediente.");
            }
            else
            {
                Object[] ingrediente = new Object[1];
                ingrediente[0] = textoIngrediente.getText();
                this.modelo.addRow(ingrediente);
                this.textoIngrediente.setText("");
                this.eliminarIngrediente.setEnabled(true);
            }
        }
        if (click == eliminarIngrediente)
        {
            this.modelo.removeRow(filaTabla);
        }
        if (click == buscarFoto)
        {
            JFileChooser chooser = new JFileChooser();
            FileNameExtensionFilter filtroImagen = new FileNameExtensionFilter("JPG & PNG", "jpg","png");
            chooser.setFileFilter(filtroImagen);
            chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
            int estado = chooser.showOpenDialog(null);
            
            if (estado == JFileChooser.APPROVE_OPTION)
            {
                File archivo = chooser.getSelectedFile();
                rutaAbsolutaImg = archivo.getAbsolutePath();
                ImageIcon imagen = new ImageIcon(rutaAbsolutaImg);
                ImageIcon imagen2 = new ImageIcon(imagen.getImage().getScaledInstance(100, 130, Image.SCALE_DEFAULT));
                this.labelFoto.setIcon(imagen2);
            }
        }
        if (click == comboBoxPlatos)
        {
            if (comboBoxPlatos.getItemCount() > 0)
            {
                String nombre = comboBoxPlatos.getSelectedItem().toString();
                llenarCamposModificables(nombre);
                habilitarEliminacion();
            }
        }
        if (click == reemplazarIngrediente)
        {
            if (textoReemplazar.getText().length() > 0) //Si hay texto
            {
                String ingredienteSustituto = textoReemplazar.getText().trim();
                String ingredienteOriginal = comboBoxIngredientes.getSelectedItem().toString();
                reemplazarIngrediente(ingredienteSustituto, ingredienteOriginal);
            }
        }
    }
    
    public void habilitarEliminacion()
    {
        if (modelo.getRowCount() == 0)
        {
            this.eliminarIngrediente.setEnabled(false);
        }
        else
        {
            this.eliminarIngrediente.setEnabled(true);
        }
    }
    
    public void llenarComboBoxPlatos()
    {
//        Object seleccionado = comboBoxPlatos.getSelectedItem();
        comboBoxPlatos.removeAllItems();
        
        for (int i=0; i<platos.size(); i++)
        {
            String nombre = platos.get(i).getNombre(); 
            
            if (!existeNombre(nombre)) //si no está el nombre...
            {
                comboBoxPlatos.addItem(nombre);
            }
        }
//        comboBoxPlatos.setSelectedItem(seleccionado);
    }
    
    public void llenarComboBoxIngredientes()
    {
        comboBoxIngredientes.removeAllItems();
        
        for (int i=0; i<platos.size(); i++) //Recorremos platos
        {
            for (int k=0; k<platos.get(i).cantidadIngredientes(); k++) //Recorremos ingredientes de dicho plato
            {
                String ingrediente = platos.get(i).getIngredientes().get(k); //ingrediente "k" del array de ingredientes de un plato
                
                if (!existeIngrediente(ingrediente)) //Si no existe ingrediente en comboBoxIngredientes
                {
                    comboBoxIngredientes.addItem(ingrediente);
                }
            }
        }
    }
    
    public boolean existeIngrediente(String ingrediente)
    {
        for (int i=0; i<comboBoxIngredientes.getItemCount(); i++)
        {
            if (ingrediente.equals(comboBoxIngredientes.getItemAt(i).toString()))
            {
                return true;
            }
        }
        return false;
    }
    
    public boolean existeNombre(String nombre)
    {
        for (int i=0; i<comboBoxPlatos.getItemCount(); i++)
        {
            if (nombre.equals(comboBoxPlatos.getItemAt(i).toString())) //Existe ya el nombre de plano en el comboBox?
            {
                return true;
            }
        }
        return false;
    }
    
    public void llenarCamposModificables(String nombre)
    {
        if (hayAlgoTxt())
        {
            for (int i=0; i<platos.size(); i++)
            {
                if (platos.get(i).getNombre().equals(nombre))
                {
                    textoNombre.setText(nombre);
                    textoPrecio.setText(platos.get(i).getPrecio()+"");
                    textoAporteCalorico.setText(platos.get(i).getAporteCalorico()+"");
                    textoValoracion.setText(platos.get(i).getValoracion()+"");
                    textoPeso.setText(platos.get(i).getPeso()+"");
                    areaDescripcion.setText(platos.get(i).getDescripcion());
                    areaRecomendacion.setText(platos.get(i).getRecomendacion());
                    updateUI();
                    indicePlatoModificado = i; //Guardamos el indice del plato actual a modificar
                    llenarTablaModificable(i);
                    i = platos.size();
                }
            }
        }
    }
    
    public void llenarTablaModificable(int indice)
    {
        while (modelo.getRowCount() > 0)
        {
            modelo.removeRow(0);
        }
        
        for (int i=0; i<platos.get(indice).getIngredientes().size(); i++)
        {
            Object[] objeto = new Object[1];
            objeto[0] = (Object)platos.get(indice).getIngredientes().get(i); //Ingrediente correspondiente al plato
            modelo.addRow(objeto);
        }
    }
    
    public void actualizarTabla()
    {
        while (modelo.getRowCount() > 0)
        {
            modelo.removeRow(0);
        }
        for (int i=0; i<platos.size(); i++) //Array platos
        {
            for (int k=0; k<platos.get(i).getIngredientes().size(); k++) //Array ingredientes de plato
            {
                Object[] objeto = new Object[1];
                objeto[0] = (Object)platos.get(i).getIngredientes().get(k);
                modelo.addRow(objeto);
            }
        }
    }
    
    public void modificarIngredientes(Plato plato)
    {
        plato.vaciarIngredientes(); //Vaciamos arraylist de ingredientes
        
        for (int i=0; i<modelo.getRowCount(); i++)
        {
            Object objeto = modelo.getValueAt(i,0);
            String ingrediente = objeto.toString();
            plato.agregarIngrediente(ingrediente);
        }
    }
    
    public void reemplazarIngrediente(String ingredienteSustituto, String ingredienteOriginal) //Buscamos en todos los platos dicho ingrediente y lo reemplazamos
    {
        for (int i=0; i<platos.size(); i++) // i para recorrer arraylist de platos
        {
            revisarIngredientesPlato(ingredienteOriginal, ingredienteSustituto, i);
        }
        if (modificadoIngrediente)
        {
            JOptionPane.showMessageDialog(this, "Ingrediente modificado exitosamente");
        }
    }
    
    public void revisarIngredientesPlato(String ingredienteOriginal, String ingredienteSustituto, int indicePlatoActual)
    {
        for (int i=0; i<platos.get(indicePlatoActual).cantidadIngredientes(); i++) //Recorremos arraylist de ingredientes de plato actual
        {
            if (ingredienteOriginal.equals(platos.get(indicePlatoActual).getIngredientes().get(i))) //Preguntamos si esta el ingrediente
            {
                platos.get(indicePlatoActual).getIngredientes().set(i, ingredienteSustituto);
                modificadoIngrediente = true;
                textoReemplazar.setText("");
                //PREGUNTAR PARA QUE NO SE CAMBIE EL COMBO BOX
                llenarComboBoxIngredientes(); //Actualizar comboBox de ingredientes totales
                llenarTablaModificable(i); //Actualizar tabla de ingredientes segun plato
                
            }
        }
    }
    
    public void reemplazarPlatoModificado(Plato plato) //Buscamos en el arraylist el plato que modificamos y lo reemplazamos por el nuevo
    {
        platos.set(indicePlatoModificado, plato);
        updateUI();
    }
    
    public void vaciarTxt() throws IOException
    {
        File archivo = new File("C:\\BaseDeDatos\\platos.txt");
        FileWriter fw = new FileWriter(archivo);
        BufferedWriter bw = new BufferedWriter(fw);
        
        bw.write("");
        bw.close();
    }
    
    public void reescribirTxt()
    {
        try
        {   
            FileWriter writer = new FileWriter("C:\\BaseDeDatos\\platos.txt", true);
            
            for (int i=0; i<platos.size(); i++)
            {
                String plato = gson.toJson(platos.get(i)); //Transformamos a String un objeto Plato
                writer.write(plato);
                writer.write("\n");
            }
            writer.close();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
    
    public void leerPlatosTxt()
    {
        File archivo = null;
        FileReader fr = null;
        BufferedReader br = null;
        platos.clear();
        
        try
        {
            archivo = new File("C:\\BaseDeDatos\\platos.txt");
            fr = new FileReader (archivo);
            br = new BufferedReader(fr);
            
            String linea;
            
            while((linea=br.readLine())!=null)
            {
                Plato plato = (Plato)gson.fromJson(linea, Plato.class);
                platos.add(plato);
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            try
            {
                if( null != fr )
                {   
                    fr.close();     
                }                  
            }
            catch (Exception e2)
            {
                e2.printStackTrace();
            }
        }
    }
    
    public boolean hayAlgoTxt()
    {
        File archivo = new File("C:\\BaseDeDatos\\platos.txt");
        
        if (archivo.length() == 0)
        {
            return false; //No hay nada
        }
        return true; //Hay algo escrito
    }
    
    public ArrayList<Plato> getPlatos()
    {
        return this.platos;
    }
    
    @Override
    public void mouseClicked(MouseEvent e) {
        if (e.getClickCount() == 1)
        {
            this.filaTabla = tabla.rowAtPoint(e.getPoint()); //Obtenemos la fila donde se ha hecho click
        }
    }

    @Override
    public void mousePressed(MouseEvent e) {}

    @Override
    public void mouseReleased(MouseEvent e) {}

    @Override
    public void mouseEntered(MouseEvent e) {}

    @Override
    public void mouseExited(MouseEvent e) {}
}
